package cn.jbolt.core.api;

import cn.jbolt.core.cache.JBoltOnlineUserCache;
import cn.jbolt.core.common.enums.JBoltApplicationType;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.Application;
import cn.jbolt.core.para.JBoltParaValidator;
import cn.jbolt.core.util.JBoltArrayUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.jfinal.kit.StrKit;

import java.util.ArrayList;
import java.util.List;

/**
 * JBolt平台API使用的工具类 只要处理用户和jwt相关threadLocal
 *
 * @ClassName: JBoltApiKit
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2020年4月1日
 */
public class JBoltApiKit extends JBoltParaValidator {
	/**
	 * 针对JwtParseResut的ThreadLocal
	 */
	private static final TransmittableThreadLocal<JBoltJwtParseRet> jwtTL = new TransmittableThreadLocal<JBoltJwtParseRet>();

	public static void setJwtParseRet(JBoltJwtParseRet jwtParseRet) {
		jwtTL.set(jwtParseRet);
		if (jwtParseRet.getApiUser().getIsSystemUser()) {
			JBoltUserKit.setUserId(jwtParseRet.getUserIdToLong());
		} else {
			// 如果绑定了系统用户jb_user 设置到当前线程中
			Long systemUserId = JBoltApiKit.getBindSystemUserId();
			if (systemUserId != null) {
				JBoltUserKit.setUserId(systemUserId);
			}
		}
	}

	public static void removeJwtParseRet() {
		jwtTL.remove();

		// 清除绑定的系统用户
		JBoltUserKit.removeUserId();
	}

	public static JBoltJwtParseRet getJwtParseRet() {
		return jwtTL.get();
	}

	/**
	 * 针对Application的ThreadLocal
	 */
	private static final TransmittableThreadLocal<Application> applicationTL = new TransmittableThreadLocal<Application>();

	public static void setApplication(Application application) {
		applicationTL.set(application);
	}

	public static void removeApplication() {
		applicationTL.remove();
	}

	/**
	 * 获得用户访问来自哪个Application
	 *
	 * @return
	 */
	public static Application getApplication() {
		return applicationTL.get();
	}

	/**
	 * 获得用户访问来自哪个Application的appId
	 *
	 * @return
	 */
	public static String getAppId() {
		Application application = getApplication();
		return application == null ? null : application.getAppId();
	}

	/**
	 * 获得用户访问来自哪个Application的主键ID
	 *
	 * @return
	 */
	public static Long getApplicationId() {
		Application application = getApplication();
		return application == null ? null : application.getId();
	}

	/**
	 * 获得用户访问来自哪个Application的主键ID string类型
	 *
	 * @return
	 */
	public static String getApplicationIdToStr() {
		Application application = getApplication();
		if(application == null){return null;}
		Long id = application.getId();
		return id == null ? null : id.toString();
	}

	/**
	 * 是否内置应用
	 *
	 * @return
	 */
	public static boolean getApplicationIsInner() {
		Application application = getApplication();
		return application != null && application.getIsInner();
	}

	/**
	 * 是否内置应用 并且是系统后台自身PC端
	 *
	 * @return
	 */
	public static boolean getApplicationIsPCInnerPlatform() {
		Application application = getApplication();
		return application != null && (application.getIsInner()
				&& application.getType() == JBoltApplicationType.INNER_PLATFORM.getValue());
	}

	@SuppressWarnings("unchecked")
	public static <T> T getApplicationIdAs() {
		Application application = getApplication();
		return application == null ? null : ((T) application.getId());
	}

	/**
	 * 获得当前访问的userId 是否是系统jb_user里的系统用户
	 *
	 * @return
	 */
	public static boolean isSystemUser() {
		JBoltApiUser apiUser = getApiUser();
		return apiUser != null && apiUser.getIsSystemUser();
	}

	/**
	 * 获得当前访问的userId
	 *
	 * @return
	 */
	public static Object getApiUserId() {
		JBoltJwtParseRet jwtParseRet = getJwtParseRet();
		return jwtParseRet == null ? null : jwtParseRet.getUserId();
	}

	/**
	 * 获得当前访问的userId
	 *
	 * @return
	 */
	public static Long getApiUserIdToLong() {
		JBoltJwtParseRet jwtParseRet = getJwtParseRet();
		return jwtParseRet == null ? null : jwtParseRet.getUserIdToLong();
	}

	/**
	 * 获得当前访问的onlineUserId
	 *
	 * @return
	 */
	public static Long getApiOnlineUserId() {
		JBoltApiUser user = getApiUser();
		return user == null ? null : user.getOnlineUserId();
	}

	/**
	 * 获得当前访问的onlineUser sessionId
	 *
	 * @return
	 */
	public static String getApiOnlineUserSessionId() {
		JBoltApiUser user = getApiUser();
		return user == null ? null : JBoltOnlineUserCache.me.getSessionId(user.getOnlineUserId());
	}

	/**
	 * 获得当前访问的userId
	 *
	 * @return
	 */
	public static Integer getApiUserIdToInt() {
		JBoltJwtParseRet jwtParseRet = getJwtParseRet();
		return jwtParseRet == null ? null : jwtParseRet.getUserIdToInt();
	}

	/**
	 * 获得当前访问的userId
	 *
	 * @return
	 */
	public static String getApiUserIdToStr() {
		JBoltJwtParseRet jwtParseRet = getJwtParseRet();
		return jwtParseRet == null ? null : jwtParseRet.getUserIdToStr();
	}


	/**
	 * 获得当前访问的userId
	 *
	 * @param <T>
	 * @return
	 */
	public static <T> T getApiUserIdAs() {
		Object id = getApiUserId();
		return id == null ? null : ((T) id);
	}

	/**
	 * 获得当前访问的apiUser绑定的其它用户表
	 *
	 * @return
	 */
	public static List<JBoltApiBindUserBean> getBindUsers() {
		JBoltApiUser apiUser = getApiUser();
		return apiUser == null ? null : apiUser.getBindUsers();
	}

	/**
	 * 获得当前访问的ApiUser
	 *
	 * @return
	 */
	public static JBoltApiUser getApiUser() {
		JBoltJwtParseRet jwtParseRet = getJwtParseRet();
		return jwtParseRet == null ? null : jwtParseRet.getApiUser();
	}
	private static final int BIND_USER_TYPE_SYSTEM_USER = 1;
	/**
	 * 得到绑定的系统用户jb_user的ID
	 *
	 * @return
	 */
	public static Long getBindSystemUserId() {
		return getBindUserIdToLong(BIND_USER_TYPE_SYSTEM_USER);
	}

	/**
	 * 获取绑定用户ID转为long
	 * @param bindUserType
	 * @return
	 */
	public static Long getBindUserIdToLong(int bindUserType) {
		Object bindUserId = getBindUserId(bindUserType);
		return bindUserId==null?null:Long.parseLong(bindUserId.toString());
	}

	/**
	 * 获取绑定用户ID转为Integer
	 * @param bindUserType
	 * @return
	 */
	public static Integer getBindUserIdToInt(int bindUserType) {
		Object bindUserId = getBindUserId(bindUserType);
		return bindUserId==null?null:Integer.parseInt(bindUserId.toString());
	}

	/**
	 * 获取绑定用户ID转为String
	 * @param bindUserType
	 * @return
	 */
	public static String getBindUserIdToStr(int bindUserType) {
		Object bindUserId = getBindUserId(bindUserType);
		return bindUserId==null?null:bindUserId.toString();
	}

	/**
	 * 得到绑定的其他用户的userId
	 *
	 * @return
	 */
	public static Object getBindUserId(int bindUserType) {
		List<JBoltApiBindUserBean> bindUserBeans = getBindUsers();
		if (bindUserBeans == null || bindUserBeans.size() == 0) {
			return null;
		}
		Object userId = null;
		for (JBoltApiBindUserBean bean : bindUserBeans) {
			if (bean.getType() == bindUserType) {
				userId = bean.getUserId();
				break;
			}
		}
		return userId;
	}

	/**
	 * 清空threadLocal
	 */
	public static void clear() {
		removeJwtParseRet();
		removeApplication();
		removeApplyJwtUser();
		removeWechatAppId();
		removeWechatMpId();
		removeApplyJwtTTL();
	}

	/**
	 * 针对申请jwt的ApiUser的ThreadLocal
	 */
	private static final TransmittableThreadLocal<JBoltApiUser> applyJwtUserTL = new TransmittableThreadLocal<JBoltApiUser>();

	public static void setApplyJwtUser(JBoltApiUser jBoltApiUser) {
		applyJwtUserTL.set(jBoltApiUser);
	}

	public static void removeApplyJwtUser() {
		applyJwtUserTL.remove();
	}

	public static JBoltApiUser getApplyJwtUser() {
		return applyJwtUserTL.get();
	}

	public static Long getApplyJwtOnlineUserId() {
		JBoltApiUser apiUser = applyJwtUserTL.get();
		return apiUser == null?null:apiUser.getOnlineUserId();
	}
	/**
	 * 获取application关联绑定的targetId
	 *
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getApplicationLinkTargetId() {
		Application application = getApplication();
		return application == null ? null : (T) (application.getLinkTargetId());
	}

	private static final TransmittableThreadLocal<String> wechatAppIdTL = new TransmittableThreadLocal<String>();

	/**
	 * 获取应用绑定的公众平台的APPID配置
	 *
	 * @return
	 */
	public static String getWechatAppId() {
		return wechatAppIdTL.get();
	}

	public static void setWechatAppId(String wechatAppId) {
		wechatAppIdTL.set(wechatAppId);
	}

	public static void removeWechatAppId() {
		wechatAppIdTL.remove();
	}

	private static final TransmittableThreadLocal<Long> wechatMpIdTL = new TransmittableThreadLocal<Long>();

	/**
	 * 获取应用绑定的公众平台的mpid配置
	 *
	 * @return
	 */
	public static Long getWechatMpId() {
		return wechatMpIdTL.get();
	}

	public static void setWechatMpId(Long mpid) {
		wechatMpIdTL.set(mpid);
	}

	public static void removeWechatMpId() {
		wechatMpIdTL.remove();
	}

	/**
	 * 处理绑定信息
	 *
	 * @param apiUser
	 * @param bindUser
	 * @return
	 */
	public static JBoltApiUserBean processBindUser(JBoltApiUserBean apiUser, String bindUser) {
		if (StrKit.isBlank(bindUser)) {
			return apiUser;
		}
		apiUser.setBindUsers(convertToBindUsers(bindUser));
		return apiUser;
	}

	/**
	 * 转换成Bean
	 *
	 * @param bindUser
	 * @return
	 */
	private static List<JBoltApiBindUserBean> convertToBindUsers(String bindUser) {
		String[] barray = JBoltArrayUtil.from(bindUser);
		if (barray.length == 0) {
			return null;
		}
		List<JBoltApiBindUserBean> beans = new ArrayList<JBoltApiBindUserBean>();
		JBoltApiBindUserBean bean;
		for (String bu : barray) {
			bean = covertToBindUser(bu);
			if (bean != null) {
				beans.add(bean);
			}
		}
		return beans;
	}

	private static JBoltApiBindUserBean covertToBindUser(String bindUser) {
		if (StrKit.isBlank(bindUser) || !bindUser.contains("_")) {
			return null;
		}
		String[] arr = bindUser.split("_");
		if (arr.length != 2 || StrKit.isBlank(arr[0]) || StrKit.isBlank(arr[1])) {
			return null;
		}

		return new JBoltApiBindUserBean(Integer.parseInt(arr[0].trim()), arr[1].trim());
	}






	private static final TransmittableThreadLocal<Long> applyJwtTTL = new TransmittableThreadLocal<Long>();

	public static void setApplyJwtTTL(Long ttl) {
		applyJwtTTL.set(ttl);
	}

	public static Long getApplyJwtTTL() {
		Long ttl = applyJwtTTL.get();
		if(ttl ==null || ttl.longValue()<=0){
			ttl = JBoltApiJwtManger.JWT_TTL;
		}
		return ttl;
	}

	public static void removeApplyJwtTTL() {
		applyJwtTTL.remove();
	}
}
